package com.joysuch.wwyt.report.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.base.Splitter;
import com.joysuch.wwyt.bp.entity.BpJob;
import com.joysuch.wwyt.bp.enums.ExecutiveUnitTypes;
import com.joysuch.wwyt.bp.repository.BpDepartDao;
import com.joysuch.wwyt.bp.repository.BpJobDao;
import com.joysuch.wwyt.common.constant.Constant;
import com.joysuch.wwyt.core.entity.BaseUser;
import com.joysuch.wwyt.core.repository.BaseTypeGroupItemDao;
import com.joysuch.wwyt.core.repository.BaseUserDao;
import com.joysuch.wwyt.core.support.Context;
import com.joysuch.wwyt.report.bean.ReportJobUserBean;
import com.joysuch.wwyt.report.bean.ReportRiskPointControlListBean;
import com.joysuch.wwyt.report.bean.ReportRiskPointControlSearchBean;
import com.joysuch.wwyt.report.bean.RiskControlListBean;
import com.joysuch.wwyt.report.bean.dto.ReportDeviceRiskEvaluationRecordDto;
import com.joysuch.wwyt.report.bean.dto.ReportJobRiskEvaluationRecordDto;
import com.joysuch.wwyt.report.bean.dto.ReportRiskAnalyzeListDto;
import com.joysuch.wwyt.report.bean.dto.ReportRiskEvaIdentifyDto;
import com.joysuch.wwyt.report.mapper.ReportRiskControlMapper;
import com.joysuch.wwyt.report.service.RiskControlService;
import com.joysuch.wwyt.risk.entity.vo.RiskMeasureTypeNode;
import com.joysuch.wwyt.risk.mapper.RiskControllevelsMapper;
import com.joysuch.wwyt.risk.repository.RiskPointEvaluationDetailDao;
import com.joysuch.wwyt.risk.service.RiskMeasureTypeService;
import com.joysuch.wwyt.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

import static com.joysuch.wwyt.common.constant.Constant.*;

@Slf4j
@Service
public class RiskControlServiceImpl implements RiskControlService {
    @Autowired
    private ReportRiskControlMapper reportRiskControlMapper;
    @Autowired
    private RiskPointEvaluationDetailDao evaluationDetailDao;
    @Autowired
    private BaseUserDao userDao;
    @Autowired
    private BpJobDao jobDao;
    @Autowired
    private BpDepartDao departDao;
    @Autowired
    private RiskControllevelsMapper controllevelsMapper;
    @Autowired
    private RiskMeasureTypeService measureTypeService;
    @Autowired
    private BaseTypeGroupItemDao typeGroupItemDao;

    @Override
    public Page<RiskControlListBean> findByResDepartAndControlLevel(Long pageNo, Long pageSize, Long departId, Long controlRiskLevel) {
        //分页获取数据
        com.baomidou.mybatisplus.extension.plugins.pagination.Page<RiskControlListBean> page = new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(pageNo, pageSize);
        Page<RiskControlListBean> riskControls = reportRiskControlMapper.findByResDepartAndControlLevel(page, departId, controlRiskLevel);
        riskControls.getRecords().forEach(each->{
            each.setControlLevel(getControlLevelsByPointId(each.getId()));
            each.setResponsiblePerson(getResPersonsByPoint(each.getId()));
        });
        return riskControls;
    }

    // 获取风险点下的所有管控步骤的管控层级（去重）
    private String getControlLevelsByPointId(Long pointId) {
        Long tenentId = Context.getCurrentTenantId();
        String orgCode = Context.getCurrentOrgCode();
        Set<Long> resultList = new HashSet<>();
        List<String> controlLevelsList = evaluationDetailDao.findControlLevelByPointId(pointId);
        controlLevelsList.forEach(each->{
            if (StringUtils.isNotBlank(each)){
                List<Long> departIds = Splitter.on(Constant.SPLIT_COMMA).trimResults().splitToList(each).stream().map(Long::new).collect(Collectors.toList());
                resultList.addAll(departIds);
            }
        });
        return resultList.stream().distinct().map(e -> controllevelsMapper.findNameByCode(e, tenentId, orgCode)).collect(Collectors.joining(Constant.SPLIT_COMMA));
    }

    // 获取风险点下的所有责任人(去重)
    private String getResPersonsByPoint(Long pointId) {
        List<Long> personIds = new ArrayList<>();
        // assign表中有则取assign表（新数据）
        List<String> resPersonsStrs = evaluationDetailDao.findResPersonsByPointIdForNew(pointId);
        for (String resPersonStr : resPersonsStrs) {
            personIds.addAll(StringUtil.covertJsonToLongList(resPersonStr));
        }
        // assign无则从detail中 有责任人直接取（老数据）
        if (CollectionUtils.isEmpty(personIds)) {
            List<String> personIdStrs = reportRiskControlMapper.findResPersonsByPointIdForOld(pointId);
            for (String each : personIdStrs) {
                if (StringUtils.isNotBlank(each)) {
                    List<Long> subPersonIds = Splitter.on(Constant.SPLIT_COMMA).trimResults().splitToList(each).stream().map(Long::new).collect(Collectors.toList());
                    personIds.addAll(subPersonIds);
                }
            }
        }
        return personIds.stream().distinct().map(userDao::getRealNameById).collect(Collectors.joining(Constant.SPLIT_COMMA));
    }

    @Override
    public Page<ReportRiskPointControlListBean> findRiskPointControlByDepart(ReportRiskPointControlSearchBean searchBean) {
        com.baomidou.mybatisplus.extension.plugins.pagination.Page<ReportRiskPointControlListBean> page =
                new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(searchBean.getPageNo(), searchBean.getPageSize());

        Page<ReportRiskPointControlListBean> pageData = reportRiskControlMapper.findRiskPointControlByDepart(page,searchBean.getDepartId(), searchBean.getPointType());
        List<ReportRiskPointControlListBean> list = pageData.getRecords();
        list.forEach(item->{
            item.setResponsibleDepart(convertDeparts(item.getResponsibleDepart()));
            item.setControlLevel(controlLevels(item.getControlLevel()));
            item.setResponsiblePerson(convertUsers(item.getResponsiblePerson()));
        });
        pageData.setRecords(list);
        return pageData;
    }

    @Override
    public Page<ReportJobRiskEvaluationRecordDto> findReportJobRiskEvaluationRecord(Long pageNo, Long pageSize, Long departId, Long jobId) {
        com.baomidou.mybatisplus.extension.plugins.pagination.Page<ReportJobRiskEvaluationRecordDto> page =
                new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(pageNo, pageSize);
        Page<ReportJobRiskEvaluationRecordDto> pageData = reportRiskControlMapper.findJobRiskEvaluation(page, departId, jobId);
        return pageData;
    }

    @Override
    public Page<ReportDeviceRiskEvaluationRecordDto> findReportDeviceRiskEvaluationRecord(Long pageNo, Long pageSize, Long departId, Long jobId) {
        com.baomidou.mybatisplus.extension.plugins.pagination.Page<ReportDeviceRiskEvaluationRecordDto> page =
                new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(pageNo, pageSize);
        Page<ReportDeviceRiskEvaluationRecordDto> pageData = reportRiskControlMapper.findDeviceRiskEvaluation(page, departId, jobId);
        return pageData;
    }

    @Override
    public Page<ReportRiskEvaIdentifyDto> findReportRiskEvaluationIdentify(Long pageNo, Long pageSize, Long departId, Long jobId, String pointType) {
        com.baomidou.mybatisplus.extension.plugins.pagination.Page<ReportRiskEvaIdentifyDto> page =
                new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(pageNo, pageSize);
        Page<ReportRiskEvaIdentifyDto> pageData = reportRiskControlMapper.findRiskPointEvalAnalyzeByDepart(page, departId, jobId, pointType);
        return pageData;
    }

    @Override
    public Page<ReportRiskAnalyzeListDto> findRiskAnalyzeList(Long pageNo, Long pageSize, String orgCode, Long tenentId) {
        com.baomidou.mybatisplus.extension.plugins.pagination.Page<ReportRiskAnalyzeListDto> page =
                new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(pageNo, pageSize);
        Page<ReportRiskAnalyzeListDto> analyzeList = reportRiskControlMapper.findRiskAnalyzeList(page, orgCode,tenentId);
        analyzeList.getRecords().forEach(this::riskAnalyzeListConvert);
        return analyzeList;
    }

    private String convertDeparts(String departIds){
        if(StringUtils.isEmpty(departIds)){
            return null;
        }
        List<Long> ids = Splitter.on(Constant.SPLIT_COMMA).trimResults().splitToList(departIds).stream().map(Long::new).collect(Collectors.toList());
        return ids.stream().distinct().map(departDao::findDepartNameById).collect(Collectors.joining(Constant.SPLIT_STOP));
    }

    private String convertUsers(String userIds){
        if(StringUtils.isEmpty(userIds)){
            return null;
        }
        userIds = userIds.replaceAll("\\[","").replaceAll("]","");
        List<Long> ids = Splitter.on(Constant.SPLIT_COMMA).trimResults().splitToList(userIds).stream().map(Long::new).collect(Collectors.toList());
        return ids.stream().distinct().map(userDao::getRealNameById).collect(Collectors.joining(Constant.SPLIT_STOP));
    }

    private String controlLevels(String levels){
        if(StringUtils.isEmpty(levels)){
            return null;
        }
        Long tenentId = Context.getCurrentTenantId();
        String orgCode = Context.getCurrentOrgCode();
        List<Long> ids = Splitter.on(Constant.SPLIT_COMMA).trimResults().splitToList(levels).stream().map(Long::new).collect(Collectors.toList());
        return ids.stream().distinct().map(e -> controllevelsMapper.findNameByCode(e, tenentId, orgCode)).collect(Collectors.joining(Constant.SPLIT_STOP));
    }

    private void riskAnalyzeListConvert(ReportRiskAnalyzeListDto riskAnalyze) {
        // id->name
        if (riskAnalyze.getResponsibleDepartId() != null) {
            riskAnalyze.setResponsibleDepartName(departDao.getNameById(riskAnalyze.getResponsibleDepartId()));
        }
        //        if (riskAnalyze.getResponsibleUserId() != null) {
//            riskAnalyze.setResponsibleUserName(userDao.getRealNameById(riskAnalyze.getResponsibleUserId()));
//        }
        String userName="";
        if (StringUtils.isNotBlank(riskAnalyze.getResponsibilityUserId())){
            List<Long> userIds = StringUtil.covertJsonToLongList(riskAnalyze.getResponsibilityUserId());
            for (int i = 0; i < userIds.size(); i++) {
                if (i!=0&&i!=userIds.size()-1){
                    userName=userName+",";
                }
                userName=userName+ userDao.getRealNameById(userIds.get(i));
            }
            if (riskAnalyze.getResponsibleUserId() != null) {
                riskAnalyze.setResponsibleUserName(userDao.getRealNameById(riskAnalyze.getResponsibleUserId()));
            }
            riskAnalyze.setResponsibleUserName(userName);
        }
        // 执行单位为岗位
        if (ExecutiveUnitTypes.JOB.getCode().equals(riskAnalyze.getExecutiveUnit())) {
            if (riskAnalyze.getUnitId() != null) {
                String executor = jobDao.getNameById(riskAnalyze.getUnitId());
                riskAnalyze.setJobAndExecutor(executor);
            }
        }else {
            List<Long> executorIds = StringUtil.covertJsonToLongList(riskAnalyze.getExecutor());
            if (!CollectionUtils.isEmpty(executorIds)) {
                // 所有执行人
                List<BaseUser> executors = userDao.getUsersByIds(executorIds);
                // 按岗位分组
                Map<Long, List<BaseUser>> executorJobGroup = executors.stream().collect(Collectors.groupingBy(BaseUser::getJob));
                Set<Long> jobIds = executorJobGroup.keySet();
                // 所有相关岗位数据
                List<BpJob> jobs = jobDao.findAllById(jobIds);
                // 岗位名称map
                Map<Long, String> jobNameMap = new HashMap<>();
                if (!CollectionUtils.isEmpty(jobs)) {
                    jobNameMap = jobs.stream().collect(Collectors.toMap(BpJob::getId, BpJob::getName));
                }
                // 组装
                List<String> executorDescList = new ArrayList<>();
                for (Long jobId : executorJobGroup.keySet()) {
                    List<BaseUser> userList = executorJobGroup.get(jobId);
                    String jobName = jobNameMap.get(jobId);
                    String executorNames = userList.stream().map(BaseUser::getRealName).collect(Collectors.joining(SPLIT_STOP));
                    // 岗位-人员1、人员2
                    executorDescList.add(jobName + SPLIT_HYPHEN + executorNames);
                }
                // 岗位1-人员1、人员2，岗位2-人员3、人员4
                riskAnalyze.setJobAndExecutor(String.join(SPLIT_COMMA, executorDescList));
            }
        }
        // 取数来源
        if (riskAnalyze.getDateSource() != null) {
            riskAnalyze.setDataSourceName(typeGroupItemDao.getNameById(riskAnalyze.getDateSource()));
        }
        // 管控措施类型
        if (riskAnalyze.getControlMeasuresType() != null) {
            RiskMeasureTypeNode measuresTypes = measureTypeService.findAllParentsByChildId(riskAnalyze.getControlMeasuresType());
            if (measuresTypes != null) {
                riskAnalyze.setControlMeasuresTypeName1(measuresTypes.getMeasureTypeName());
                if (!CollectionUtils.isEmpty(measuresTypes.getChilds())) {
                    RiskMeasureTypeNode son = measuresTypes.getChilds().get(0);
                    riskAnalyze.setControlMeasuresTypeName2(son.getMeasureTypeName());
                    if (!CollectionUtils.isEmpty(son.getChilds())) {
                        RiskMeasureTypeNode grandson = son.getChilds().get(0);
                        riskAnalyze.setControlMeasuresTypeName3(grandson.getMeasureTypeName());
                    }
                }
            }
        }
        //周期 日改为天
        if (riskAnalyze.getPeriodUnit()!=null&&riskAnalyze.getPeriodUnit().contains("日")) {
            riskAnalyze.setPeriodUnit(riskAnalyze.getPeriodUnit().replaceAll("日","天"));
        }
    }
}
